using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Security.Claims;
using Tiens.NotificationHub.Core;
using Tiens.NotificationHub.Core.Extensions;
using Tiens.NotificationHub.WebHost.Extensions;

namespace Tiens.NotificationHub.WebHost
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthorization(options =>
            {
                options.AddPolicy("RequiredUser",
                    policy =>
                        policy.Requirements.Add(
                            new UserRequirement(ClaimTypes.Name)));
            });

            services.AddMemoryCache()
                .AddHttpContextAccessor()
                .AddUserAuthorization(Configuration)
                .AddRedisAppConnectionManager(Configuration)
                .AddSmtpMail(Configuration)
                .AddEventBus(Configuration)
                .AddSwaggerUI()
                .AddControllers();

            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .SetIsOriginAllowed((host) => true)
                        .AllowCredentials());
            });

            services.AddSignalR()
                .AddStackExchangeRedis(Configuration["RedisStoreOptions:ConnectionString"], options => {
                    options.Configuration.ChannelPrefix = "Tiens.NotificationHub";
                    options.Configuration.Password = Configuration["RedisStoreOptions:Password"];
                });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseCors("CorsPolicy");

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();

                endpoints.MapHub<NotificationsHub>("/hub/notificationhub")
                    .RequireAuthorization("RequiredUser");
            });

            app.UseSwagger()
                .UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Notification-Hub.API V1"); });
        }
    }
}
